<template>
  <BubblingSortingTp
    :arr="arr"
    :onSort="onSort"
    :onReset="onReset"
    :boundary="boundary"
    :sortingArr="sortingArr"
    :sorting="sorting"
    :showCode="showCode"
    :arrToString="arrToString"
  >
    <template #boundary="b">
      <div><div v-if="b.key < boundary" class="complete">✓</div></div>
    </template>
  </BubblingSortingTp>
</template>
<script setup lang="ts">
import BubblingSortingTp from '@/components/BubblingSortingTp.vue'
import anime from '@/anime.es.js'
import useSort from '../useSort'
import { ref, watchEffect } from 'vue'
const {
  onReset: _onReset,
  arr,
  boundary,
  sortingArr,
  sorting,
  showCode,
  arrToString,
  myWait
} = useSort()

const exchangeArr2 = ref([] as number[])

function createPromise(el: HTMLLIElement, x: number) {
  return new Promise((resolve) => {
    anime({
      targets: el,
      translateX: x,
      duration: 500,
      easing: 'linear',
      complete: () => {
        el.style.cssText = ''
        resolve(1)
      }
    })
  })
}

watchEffect(async () => {
  if (exchangeArr2.value.length) {
    if (exchangeArr2.value.length === 2) {
      // 视觉交换位置
      const [a, b] = exchangeArr2.value
      const lis: NodeList = document.querySelectorAll('.sort-ul > li')
      const ela = lis[a] as HTMLLIElement
      const elb = lis[b] as HTMLLIElement
      const needMoveLis = [].slice.call(lis, b, a)
      const x = (lis[1] as HTMLLIElement).offsetLeft - (lis[0] as HTMLLIElement).offsetLeft
      await Promise.all([
        createPromise(ela, elb.offsetLeft - ela.offsetLeft),
        ...needMoveLis.map((item) => createPromise(item, x))
      ])
      exchangeArr2.value.push(-1)
    } else if (exchangeArr2.value.length === 3) {
      // 物理交换位置
      const [a, b] = exchangeArr2.value
      const [temp] = arr.splice(a, 1)
      arr.splice(b, 0, temp)
    }
  }
})

boundary.value = 0

async function onSort() {
  if (sorting.value) return
  sorting.value = true

  for (let i = 0; i < arr.length - 1; i++) {
    boundary.value = i
    for (let j = i + 1; j < arr.length; j++) {
      sortingArr.value = [i, j]
      await myWait(500)
      if (arr[j] < arr[i]) {
        exchangeArr2.value = [j, i]
        await myWait(600)
      }
    }
  }

  boundary.value = arr.length
  sorting.value = false
  sortingArr.value = []
}
function onReset() {
  _onReset()
  boundary.value = 0
}
</script>
<style scoped></style>
